package com.ghp.admin.aop;


import cn.hutool.core.lang.UUID;
import cn.hutool.core.util.RandomUtil;
import com.baomidou.mybatisplus.core.toolkit.sql.StringEscape;
import com.ghp.common.constants.SystemConstants;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.CharSet;
import org.apache.commons.lang3.StringUtils;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.springframework.stereotype.Component;
import org.springframework.util.StopWatch;
import org.springframework.web.context.request.RequestAttributes;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;
import java.nio.charset.StandardCharsets;
import java.util.Random;

/**
 * @author ghp
 * @title
 * @description 通过 AOP 实现对请求的日志打印
 */
@Aspect
@Component
@Slf4j
public class RequestLogAspect {

    /**
     * 为Controller包下的所用请求打印 请求日志
     */
    @Around("execution(* " + SystemConstants.CONTROLLER_PACKAGE_PATH + ".*.*(..))")
    public Object doInterceptor(ProceedingJoinPoint point) throws Throwable {
        // 计时
        StopWatch stopWatch = new StopWatch();
        stopWatch.start();

        // 打印请求日志
        RequestAttributes requestAttributes = RequestContextHolder.currentRequestAttributes();
        HttpServletRequest request = ((ServletRequestAttributes) requestAttributes).getRequest();
        // 生成本次请求的唯一 id
        String requestId = request.getRequestedSessionId();
        // 本次请求的URI
        String uri = request.getRequestURI();
        // 本次请求的IP
        String host = request.getRemoteHost();
        // 本次请求的参数
        Object[] args = point.getArgs();
        String params = "[" + StringUtils.join(args, ", ") + "]";
        // 输出请求日志
        log.info("==================Start=======================");
        log.info("请求ID: {}", requestId);
        log.info("请求URI: {}", uri);
        log.info("请求IP: {}", host);
        log.info("请求参数: {}", StringEscape.escapeString(params));

        // 执行原方法
        Object result = point.proceed();

        // 输出响应日志
        stopWatch.stop();
        long totalTimeMillis = stopWatch.getTotalTimeMillis();
        log.info("本次请求耗时: {}ms", totalTimeMillis);
        log.info("=====================End=====================");
        return result;
    }
}

